package com.cn.nio.demo;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

@Slf4j
public class Client {

  public static void main(String[] args) {

    Selector selector = null;
    try {
      selector = Selector.open();
    } catch (IOException e) {
      e.printStackTrace();
    }
    for (int i = 0; i < 1; i++) {
      extracted(selector);
    }

  }

  private static void extracted(Selector selector) {
    try {
      SocketChannel connectSocketChannel = SocketChannel.open();
      connectSocketChannel.configureBlocking(false);
      connectSocketChannel.connect(new InetSocketAddress("127.0.0.1", 8090));
      connectSocketChannel.register(selector, SelectionKey.OP_CONNECT);
      log.info("start ...");
      while (true) {
        selector.select();
        Set<SelectionKey> selectionKeys = selector.selectedKeys();
        Iterator<SelectionKey> iterator = selectionKeys.iterator();
        boolean exit = false;
        while (iterator.hasNext()) {
          SelectionKey next = iterator.next();
          iterator.remove();
          boolean valid = next.isValid();
          if (!valid) {
            log.info("{} valid", next);
          }

          if (next.isConnectable()) {
            SocketChannel newSocket = (SocketChannel) next.channel();
            if (newSocket.finishConnect()) {
              newSocket.register(selector, SelectionKey.OP_WRITE);
            }
          } else if (next.isReadable()) {
            SocketChannel socketChannel = (SocketChannel) next.channel();
            ByteBuffer allocate = ByteBuffer.allocate(128);
            int read = socketChannel.read(allocate);
            allocate.flip();
//            if (read <= 0) {
//              socketChannel.close();//读取不到数据就断开连接
//              log.info("close");
//              exit = true;
//              break;
//            }
            log.info("{}", new String(allocate.array(), StandardCharsets.UTF_8));
            socketChannel.register(selector,SelectionKey.OP_WRITE);
          } else if (next.isWritable()) {
            SocketChannel socketChannel = (SocketChannel) next.channel();
            Scanner scanner = new Scanner(System.in);
            String s = "client: message " +scanner.nextLine() + "  at " + System.currentTimeMillis();
            ByteBuffer allocate = ByteBuffer.allocate(128);
            allocate.put(s.getBytes(StandardCharsets.UTF_8));
            allocate.flip();
            socketChannel.write(allocate);

            socketChannel.register(selector, SelectionKey.OP_READ);
          }
        }
        if (exit) break;
      }
      log.info("exit");

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}
